package com.lark.web.ssh.service;

import com.jcraft.jsch.*;
import com.lark.common.exception.CustomException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author fei
 */
@Service
public class SSHUtil {

    private static Map<String, Session> sessionMap = new HashMap<>();
    private static Map<String, ChannelShell> shellChannelMap = new HashMap<>();// 有用

    /**
     * openSession会话
     *
     * @param host
     * @param port
     * @param user
     * @param password
     * @return
     */
    public static Session openSession(String host, int port, String user, String password) {
        if (StringUtils.isBlank(user) || StringUtils.isBlank(password)) {
            throw new CustomException("请填写正确的账号和密码!");
        }
        Session session = null;
        try {
            if (Objects.isNull(sessionMap.get(host))) {
                JSch jsch = new JSch();
                session = jsch.getSession(user, host, port);
                session.setConfig("StrictHostKeyChecking", "no");
                session.setPassword(password);
                session.setTimeout(30 * 60 * 1000);
                session.connect();
//                sessionMap.put(host, session);
            } else {
                session = sessionMap.get(host);
            }

        } catch (JSchException e) {
            e.printStackTrace();
        }
        return session;
    }

    /**
     * 执行命令
     *
     * @param session
     * @param command
     * @return
     */
    public static String exec(Session session, String command) {
        String out = "";
        try {
            ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
            channelExec.setCommand(command);
            InputStream in = channelExec.getInputStream();
            channelExec.setErrStream(System.err);
            channelExec.connect();
            out = IOUtils.toString(in, "UTF-8");
            channelExec.disconnect();
        } catch (JSchException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            session.disconnect();
        }
        return out;
    }

    /**
     * 执行命令
     *
     * @param session
     * @param command
     * @return
     */
    public static String execSocket(Session session, String term, String command) {
        String out = "";
        try {
            ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
            channelExec.setCommand(command);
            InputStream in = channelExec.getInputStream();
            channelExec.setErrStream(System.err);
            channelExec.connect();
            out = IOUtils.toString(in, "UTF-8");
            channelExec.disconnect();
        } catch (JSchException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out;
    }

    public static void closeChannel(Session session, String term) {
        if (Objects.isNull(session)) {
//            shellChannelMap.get(session.getHost() + term).disconnect();
            shellChannelMap.remove(session.getHost() + term);
        }
    }

    /**
     * 上传文件
     */
    public static void uploadFile(Session session, String destPath, InputStream inputStream) {
        Channel channel = null;
        try {
            channel = session.openChannel("sftp");// 打开SFTP通道
            channel.connect();// 建立SFTP通道的连接
            ChannelSftp chSftp = (ChannelSftp) channel;
            chSftp.put(inputStream, destPath, ChannelSftp.OVERWRITE);
            chSftp.quit();
            channel.disconnect();
        } catch (JSchException e) {
            throw new RuntimeException(e);
        } catch (SftpException e) {
            throw new RuntimeException(e);
        } finally {
            session.disconnect();
        }
    }

    /**
     * 下载文件
     */
    public static void downloadFile(Session session, String srcFileName, OutputStream outputStream) throws IOException {
        Channel channel = null;
        try {
            channel = session.openChannel("sftp");// 打开SFTP通道
            channel.connect();// 建立SFTP通道的连接
            ChannelSftp chSftp = (ChannelSftp) channel;
            chSftp.get(srcFileName, outputStream);
            outputStream.flush();
            chSftp.quit();
            channel.disconnect();
        } catch (JSchException e) {
            throw new RuntimeException(e);
        } catch (SftpException e) {
            throw new RuntimeException(e);
        } finally {
            session.disconnect();
        }

    }

    /**
     * 判断文件类型
     */
    public static String getTypeOfFile(String permission) {
        if (permission.startsWith("d", 0)) {
            return "directory";
        } else if (permission.startsWith("l", 0)) {
            return "symbolic_link";
        } else if (permission.startsWith("-", 0)) {
            return "regular_file";
        } else {
            return "regular_file";
        }
    }

    /**
     * 截取日期
     *
     * @param dateString
     * @return
     */
    public static String subDateString(String dateString) {
        int end = dateString.lastIndexOf(".");
        return dateString.substring(0, end);
    }

    /**
     * 分割字段
     *
     * @param line
     * @return
     */
    public static List<String> ignoreNull(String line) {
        List<String> list = new ArrayList<>();
        String[] splitArray = line.split(" ");
        for (String string : splitArray) {
            if (StringUtils.isNotBlank(string)) {
                list.add(string);
            }
        }
        return list;
    }
}
